home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 May
/
EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso
/
earcd
/
util
/
sys
/
msys_1_2.lha
/
Src
/
requestchoice.c
< prev
Wrap
C/C++ Source or Header
|
1996-12-27
|
9KB
|
282 lines
/*
** requestchoice.c - request information from user
** $VER: requestchoice.c 42.2 (27.12.96)
** Copyright © 1996 Michal Letowski
**
** 42.1 (4.7.96) - initial version
** 42.2 (27.12.96)
** ! an invisible window was left on public screens - fixed
** + now reacts to break signal
*/
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <intuition/intuition.h>
#include <utility/tagitem.h>
#include <support/types.h>
#include <support/exec.h>
#include <support/dos.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include "requestchoice.rev.h"
/*
** Constants
*/
#define DOS_NAME "dos.library"
#define DOS_VERN 37L
#define INT_NAME "intuition.library"
#define INT_VERN 37L
#define TEMPLATE "TITLE/A,BODY/A,GADGETS/A/M,PUBSCREEN/K,TIMEOUT/K/N"
#define DELAY_AMOUNT 10
#define MICROS_PER_SECOND 1000000
#define MicroTime(s,m) (CurrentTime(&(s),&(m)), (s)*MICROS_PER_SECOND+(m))
/*
** Private structures
*/
struct Options
{
STRPTR opt_Title; /* TITLE/A */
STRPTR opt_Body; /* BODY/A */
STRPTR *opt_Gadgets; /* GADGETS/A */
STRPTR opt_PubScreen; /* PUBSCREEN/K */
LONG *opt_Timeout; /* TIMEOUT/K/N */
}; /* Options */
/*
** Global data
*/
STATIC CONST TEXT VersionString[]=
VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
/*
** Level 1 private functions prototypes
*/
STATIC STRPTR CreateGadgetString(STRPTR *gadgets);
/*
** Public functions
*/
/****** C/RequestChoice *****************************************************
*
* NAME
* RequestChoice -- create and handle a decision requester. (V39)
*
* SYNOPSIS
* RequestChoice Title Body Button1 Button2 ... ButtonN
* [PUBSCREEN=PubScreenName] [TIMEOUT=TimeoutValue]
*
* TEMPLATE
* RequestChoice "TITLE/A,BODY/A,GADGETS/A/M,PUBSCREEN/K,TIMEOUT/K/N"
*
* FUNCTION
* Opens a requester window on a given public screen with a choice of
* one or more buttons. Chosen button number is printed. Buttons are
* numbered from left to right, with the leftmost button being number
* 1. The rightmost button has a number 0 assigned to it. If there is
* only one button, it is treated as 0.
* A requester can cancel itself after a specified amount of time. In
* such case 0 is returned and printed.
*
* INPUTS
* TITLE - a title of the requester window.
* BODY - a text to appear inside requester window.
* GADGETS - one or more strings representing button texts.
* PUBSCREEN - name of the public screen the requester should appear on.
* If the screen is unavailable, the requester will appear
* on default public screen - in most cases Workbench.
* TIMEOUT - a value given in seconds after which a requester will
* cancel itself.
*
* RESULT
* RETURN_FAIL - if 'dos.library' or 'intuition.library' couldn't be
* opened.
* RETURN_ERROR - if command line arguments couldn't be processed or
* there wasn't enough memory.
* RETURN_WARN - if a given public screen couldn't be found or there
* was a problem building a requster.
* RETURN_OK - if everything went OK.
*
* EXAMPLE
* RequestChoice "Test1" "Choose OK or Cancel" "OK" "Cancel"
* ; Puts a requester with 'Test' title, 'Choose OK or Cancel' text
* ; inside requester window and two buttons named 'OK' and
* ; 'Cancel'. If a user presses 'OK', '1' will be printed. If a
* ; user presses 'Cancel', '0' will be printed.
* RequestChoice "Test2" "Select number" "1" "2" "3" "4" "5"
* PUBSCREEN="DOPUS.1" TIMEOUT=10
* ; Puts a requester with five choices buttons on Directory Opus'
* ; screen. If a user doesn't press any button within ten seconds,
* ; a requester will cancel itself and '0' will be printed.
*
* NOTES
* This version of the command differs from original in that it will
* create a requester even if a given public screen doesn't exist.
*
* BUGS
* Timeouts are precise to about 1/3 of a second.
*
* SEE ALSO
* intuition.library/EasyRequestArgs().
*
*****************************************************************************
*
*/
LONG RequestChoice(VOID)
{
STATIC CONST struct TagItem WinTags[]=
{
{WA_Left, 0},
{WA_Top, 0},
{WA_Width, 16},
{WA_Height, 16},
{WA_Backdrop, TRUE},
{WA_Borderless, TRUE},
{WA_NoCareRefresh, TRUE},
{WA_RMBTrap, TRUE},
{TAG_DONE, 0}
}; /* WinTags */
struct ExecBase *SysBase=INITSYSBASE;
struct Library *DOSBase;
struct Library *IntuitionBase;
struct Options Opts;
struct EasyStruct ES;
struct RDArgs *Args;
struct Window *Win=NULL,*Req;
STRPTR GadBuf;
ULONG Secs,Mics,Time;
LONG ReqRes,RC=RETURN_FAIL;
/* Open DOS */
unless(DOSBase=OpenLibrary(DOS_NAME,DOS_VERN))
throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY), NO_DOS);
/* Open Intuition */
unless(IntuitionBase=OpenLibrary(INT_NAME,INT_VERN))
throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,PROG_NAME), NO_INT);
RC=RETURN_ERROR; /* Working a bit... */
/* Read arguments */
clear(&Opts); /* Clear out buffer */
unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
throw2(PrintFault(IoErr(),PROG_NAME), NO_ARGS);
/* Merge gadgets strings into one big string */
unless(GadBuf=CreateGadgetString(Opts.opt_Gadgets))
throw2(PrintFault(IoErr(),PROG_NAME), NO_MEM);
RC=RETURN_OK; /* Everything seems to be ok... */
/* Prepare EasyRequest structure */
ES.es_StructSize=sizeof(ES);
ES.es_Flags=0;
ES.es_Title=Opts.opt_Title;
ES.es_TextFormat="%s";
ES.es_GadgetFormat="%s";
/* If public screen given, create a dummy window on it */
if(Opts.opt_PubScreen)
unless(Win=OpenWindowTags(NULL, WA_PubScreenName, Opts.opt_PubScreen,
TAG_MORE, WinTags))
RC=RETURN_WARN; /* Warning if no public screen */
/* Create requester */
Req=BuildEasyRequest(Win,&ES,NULL,Opts.opt_Body,GadBuf);
if(Win)
CloseWindow(Win); /* Close window (if any) */
/* Handle requester */
if((ULONG)Req>1) /* Created successfully... */
{
/* Handle requester */
if(Opts.opt_Timeout)
Time=MicroTime(Secs,Mics)+
clamp(*Opts.opt_Timeout,0,MAXINT/MICROS_PER_SECOND)*MICROS_PER_SECOND;
forever
{
ReqRes=SysReqHandler(Req,NULL,FALSE); /* Handle requester input */
if(ReqRes>=0 || CheckSignal(SIGBREAKF_CTRL_C))
break; /* Out of loop if gadget chosen or break */
if(Opts.opt_Timeout && MicroTime(Secs,Mics)>=Time)
break; /* Out of loop if timeout */
Delay(DELAY_AMOUNT); /* Wait a moment */
} /* forever */
FreeSysRequest(Req); /* Remove requester */
} /* if */
else /* Created successfully */
{
ReqRes=(LONG)Req; /* Set result */
RC=RETURN_WARN; /* So warn user */
} /* else */
/* Print result */
Printf("%ld\n",ReqRes<0 ? 0 : ReqRes); /* 0 if timeout, else gadget code */
/* Exceptions */
catch(BAD_ARGS, );
catch(NO_MEM, FreeVec(GadBuf));
catch(NO_ARGS, FreeArgs(Args));
catch(NO_INT, CloseLibrary(IntuitionBase));
catch(NO_DOS, CloseLibrary(DOSBase));
return(RC);
} /* RequestChoice */
/*
** Level 1 private functions
*/
STATIC STRPTR CreateGadgetString(STRPTR *gadgets)
{
struct ExecBase *SysBase=INITSYSBASE;
STRPTR *ArgPtr,CurArg,GadBuf,CurBuf;
LONG GadLen=0;
/* Process all gadgets strings */
ArgPtr=gadgets;
while(CurArg=*ArgPtr++) /* For each gadget string */
GadLen+=strlen(CurArg)+1; /* Add length of current string */
GadLen++; /* NULL terminator, GadLen>0 */
/* Allocate memory for gadgets string */
if(GadBuf=AllocVec(GadLen,MEMF_PUBCLR)) /* Try to allocate memory for merged strings */
{ /* OK - merge strings */
CurBuf=GadBuf;
ArgPtr=gadgets; /* First gadgets string */
while(CurArg=*ArgPtr++) /* For each gadget string */
{
GadLen=strlen(CurArg); /* Find length of gadget string */
MemCopy(CurBuf,CurArg,GadLen); /* Copy gadget string to buffer */
CurBuf+=GadLen; /* Advance buffer */
*CurBuf++='|'; /* Add separator */
}
*(CurBuf-1)='\0'; /* Change last '|' into NULL */
}
return(GadBuf);
} /* CreateGadgetString */